package com.zzz.system.service;

import com.google.common.collect.Lists;
import com.mybatisflex.core.query.If;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.service.IService;
import com.mybatisflex.core.util.UpdateEntity;
import com.zzz.codegen.FastGenerator;
import com.zzz.codegen.config.GlobalConfig;
import com.zzz.codegen.config.TemplateConfig;
import com.zzz.codegen.entity.GenResult;
import com.zzz.codegen.entity.TableVO;
import com.zzz.framework.exception.BizException;
import com.zzz.framework.model.PageResult;
import com.zzz.framework.model.R;
import com.zzz.framework.util.MyBeanUtil;
import com.zzz.system.entity.Template;
import com.zzz.system.mapper.TemplateMapper;
import com.zzz.system.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.zzz.system.entity.table.TemplateTableDef.TEMPLATE;

@Service
public class TemplateService implements IService<Template> {
    @Autowired
    private TemplateMapper templateMapper;
    @Autowired
    private DataSourceService dataSourceService;
    @Autowired
    private TemplateGroupService templateGroupService;

    @Override
    public TemplateMapper getMapper() {
        return templateMapper;
    }

    public List<TemplateVO> findByGroupCode(String groupCode) {
        return MyBeanUtil.copyList(getMapper().findByGroupCode(groupCode), TemplateVO.class);
    }

    public TemplateVO findByGroupCodeAndCode(String groupCode, String code) {
        return MyBeanUtil.copyBean(getMapper().findByGroupCodeAndCode(groupCode, code), TemplateVO.class);
    }

    public TemplateVO findById(Long id) {
        return MyBeanUtil.copyBean(getById(id), TemplateVO.class);
    }

    public TemplateVO findById(Long id, String dataSourceCode, String tableName) {
        TemplateVO templateVO = findById(id);
        pushFileContent(Lists.newArrayList(templateVO), dataSourceCode, tableName);
        return templateVO;
    }

    public List<TemplateVO> findByGroupCode(String groupCode, String dataSourceCode, String tableName) {
        List<TemplateVO> templateVOList = findByGroupCode(groupCode);
        pushFileContent(templateVOList, dataSourceCode, tableName);
        return templateVOList;
    }

    public TemplateVO previewByContent(PreviewTemplateVO previewTemplateVO) {
        TemplateVO templateVO = findById(previewTemplateVO.getId());
        templateVO.setContent(previewTemplateVO.getContent());
        pushFileContent(Lists.newArrayList(templateVO), previewTemplateVO.getDataSourceCode(), previewTemplateVO.getTableName());
        return templateVO;
    }

    public PageResult<TemplateVO> findByCondition(QueryTemplateVO queryVO) {
        QueryWrapper query = QueryWrapper.create()
                .from(TEMPLATE)
                .where(TEMPLATE.CODE.like(queryVO.getCode(), If::hasText))
                .and(TEMPLATE.GROUP_CODE.eq(queryVO.getGroupCode(), If::hasText))
                .orderBy(TEMPLATE.ID, false);
        return getMapper().findByCondition(queryVO.getPage(), queryVO.getPageSize(), query, TemplateVO.class);
    }

    /**
     * 填充根据文档生成的文件内容
     *
     * @param templates
     * @param dataSourceCode
     * @param tableName
     */
    private void pushFileContent(Collection<TemplateVO> templates, String dataSourceCode, String tableName) {
        if (StringUtils.isBlank(dataSourceCode) || StringUtils.isBlank(tableName)) {
            return;
        }
        DataSource ds = dataSourceService.getDs(dataSourceCode);
        if (ds == null) {
            return;
        }
        List<TableVO> tableVOList = FastGenerator.buildTableVOListByTableNames(ds, Lists.newArrayList(tableName));

        TemplateGroupVO groupVO = templateGroupService.findByCode(templates.stream().findFirst().get().getGroupCode());
        List<TemplateVO> templateVOList = findByGroupCode(groupVO.getCode());
        Map<String, TemplateVO> currMap = templates.stream().collect(Collectors.toMap(t -> t.getCode(), t -> t, (v1, v2) -> v2));
        //创建配置内容
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setGroup(groupVO.toGroupConfig());
        for (TemplateVO templateVO : templateVOList) {
            TemplateVO curr = currMap.get(templateVO.getCode());
            if (curr != null) {
                TemplateConfig config = curr.toTemplateConfig().setGenerateEnable(true);
                //生成模板内容
                globalConfig.registerTemplateConfig(config);
            } else {
                TemplateConfig config = templateVO.toTemplateConfig().setGenerateEnable(false);
                //其他只是用来做参数
                globalConfig.registerTemplateConfig(config);
            }
        }
        List<GenResult> genResultList = FastGenerator.generateByTableVOList(globalConfig, tableVOList);
        Map<String, GenResult> genResultMap = genResultList.stream().collect(Collectors.toMap(t -> t.getGenType(), t -> t, (v1, v2) -> v2));
        //填充模板生成内容
        for (TemplateVO templateVO : templates) {
            GenResult genResult = genResultMap.get(templateVO.getCode());
            if (genResult != null) {
                templateVO.setCreateFileContent(genResult.getGenContent());
                templateVO.setCreateFilePath(genResult.getFilePath());
            }
        }
    }

    public R edit(SaveTemplateVO saveTemplateVO) {
        Template templateDO = getById(saveTemplateVO.getId());
        if (templateDO == null) {
            throw new BizException("操作的数据不存在");
        }
        Template updateBean = UpdateEntity.of(Template.class);
        MyBeanUtil.copyBean(saveTemplateVO, updateBean);
        return R.data(updateById(updateBean));
    }

    public R add(SaveTemplateVO saveTemplateVO) {
        Template addBean = MyBeanUtil.copyBean(saveTemplateVO, Template.class);
        addBean.setId(null);
        return R.data(save(addBean));
    }

    public R remove(Long id) {
        Template bean = getById(id);
        if (bean == null) {
            throw new BizException("操作的数据不存在");
        }
        return R.data(removeById(id));
    }

    public void insertBatch(List<Template> batchTemplates) {
        saveBatch(batchTemplates);
    }


}
